<?php

class Application_Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{

	protected function _initFrontcontroller()
	{

		$front = Zend_Controller_Front::getInstance();
		$front -> setDefaultModule('core') -> setParam('prefixDefaultModule', true);
		$front -> setParam('useDefaultControllerAlways', false);
		$front -> registerPlugin(new Nuo_Controller_Plugin_Bootstrap);
		
		return $front;

	}

	/**
	 * initial database at first
	 */
	protected function _initDb()
	{
		$file = SETTING_PATH . '/database.php';

		$options =
		include $file;

		$db = Zend_Db::factory($options['adapter'], $options['params']);

		/**
		 * reset fetch mode
		 */
		$db -> setFetchMode(Zend_Db::FETCH_OBJ);

		// set default table adpater
		Zend_Db_Table_Abstract::setDefaultAdapter($db);

		// set table prefix
		Nuo::setTablePrefix($options['tablePrefix']);

		// Non-production
		if (APPLICATION_ENV !== 'production')
		{
			$db -> setProfiler(array(
					'class' => 'Zend_Db_Profiler_Firebug',
					'enabled' => true
			));
		}

		// set DB to UTC timezone for this session
		switch( $options['adapter'] ) {
			case 'mysqli' :
			case 'mysql' :
			case 'pdo_mysql' : {
				$db -> query("SET time_zone = '+0:00'");
				break;
			}

			case 'postgresql' : {
				$db -> query("SET time_zone = '+0:00'");
				break;
			}

			default : {
				// do nothing
			}
		}

		// attempt to disable strict mode
		try
		{
			$db -> query("SET SQL_MODE = ''");
		}
		catch (Exception $e)
		{
		}

		return $db;
	}

	protected function _initObjectTypes()
	{
		Nuo::setObjectTypes(
		require SETTING_PATH . '/objects.php');
	}

	/**
	 * init view
	 */
	protected function _initView()
	{
		require_once 'Nuo/View.php';
				
		// Create view
		$view = new Nuo_View();
		
		$view-> setEncoding('UTF-8');
		
		// Setup and register viewRenderer
		// @todo we may not need to override zend's
		$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);

		$viewRenderer = new Zend_Controller_Action_Helper_ViewRenderer($view);
		$viewRenderer -> setViewSuffix('phtml');

		Zend_Controller_Action_HelperBroker::getStack() -> offsetSet(-80, $viewRenderer);

		// Initialize contextSwitch helper
		// Zend_Controller_Action_HelperBroker::addHelper(new
		// Core_Controller_Action_Helper_ContextSwitch());

		// Add default helper paths
		$view -> addScriptPath(APPLICATION_PATH . '/modules/Core/views/scripts')
		-> addHelperPath(LIBRARY_PATH . '/Nuo/View/Helper', 'Nuo_View_Helper')
		-> addHelperPath(APPLICATION_PATH . 'modules/Core/views/helpers', 'Core_View_Helper_');
		
		// set doctype
		$view-> doctype('HTML4_STRICT');
		
		// set encoding
		

		// $doctypeHelper->doctype(Engine_Api::_()->getApi('settings',
		// 'core')->getSetting('core.doctype', 'HTML4_LOOSE'));

		// Add to local container and registry
		Zend_Registry::set('Zend_View', $view);

		// print_r($view -> getHelperPaths());
		// exit ;

		return $view;
	}

	/**
	 * init module
	 */
	protected function _initPlugins()
	{
		$front = Zend_Controller_Front::getInstance();

		// available module
		$modules = array(
				'core',
				'user'
		);

		$db = Zend_Db_Table::getDefaultAdapter();

		$table = Nuo::getTableName('core_plugins');

		$rows = $db -> fetchAll("SELECT * FROM `nuo_core_plugins` WHERE enabled=1 ORDER BY priority ASC");

		foreach ($rows as $row)
		{
			$plugin = $row -> plugin;

			Nuo::addModule($plugin);

			$path = APPLICATION_PATH . '/modules/' . Nuo::inflect($plugin) . '/controllers';

			$front -> addControllerDirectory($path, $plugin);
		}

		// module
	}

	protected function _initRoutes()
	{
		$front = Zend_Controller_Front::getInstance();

		// add default routers
		$router = $front -> getRouter();

		// metch all routers

		$db = Zend_Db_Table::getDefaultAdapter();
		$table = Nuo::getTableName('core_routes');

		$router -> addRoute('admin', Nuo_Controller_Router_Route_ControllerPrefix::getInstance(new Zend_Config( array())));

		// add all routes as defined.
		foreach ($db->fetchAll("select * from $table where enabled=1 ORDER BY priority ASC") as $row)
		{
			$params = unserialize($row -> params);
			$router -> addRoute($row -> name, new Zend_Controller_Router_Route($params['route'], $params['defs'], $params['reqs']));
		}
		// start by first router

		$router -> addDefaultRoutes();

	}

	/**
	 * init layout
	 */
	protected function _initLayout()
	{
		// Create layout
		$layout = Zend_Layout::startMvc();

		// Set options
		$layout -> setViewBasePath(APPLICATION_PATH . "/layouts/default", 'Layout_Views') -> setLayout('index');

		return $layout;
	}

	// init hooks
	protected function _initHooks()
	{
		$db = Zend_Db_Table::getDefaultAdapter();
		$table = Nuo::getTableName('core_hooks');
		$arr = array();
		foreach ($db->fetchAll("SELECT * FROM $table where enabled = 1 order by priority") as $row)
		{
			$arr[$row -> event_name][] = explode('.', $row -> event_handler);
		}
		// batch hooks
		Nuo::setHooks($arr);
	}

	protected function _initLog()
	{
		$log = new Zend_Log();

		$log -> setEventItem('domain', 'error');

		// Non-production
		if (APPLICATION_ENV !== 'production')
		{
			$log -> addWriter(new Zend_Log_Writer_Firebug());
		}

		// Get log config

		$logAdapter = 'file';
		$filename = LOG_PATH . '/main.log';

		try
		{
			$log -> addWriter(new Zend_Log_Writer_Stream($filename));
		}
		catch( Exception $e )
		{
			// Check directory
			if (!@is_dir(LOG_PATH) && @mkdir(LOG_PATH, 0777, true))
			{
				$log -> addWriter(new Zend_Log_Writer_Stream($filename));
			}
			else
			{
				// Silence ...
				if (APPLICATION_ENV !== 'production')
				{
					$log -> log($e -> __toString(), Zend_Log::CRIT);
				}
				else
				{
					// Make sure logging doesn't cause exceptions
					$log -> addWriter(new Zend_Log_Writer_Null());
				}
			}
		}

		// Save to registry
		Zend_Registry::set('Zend_Log', $log);

		// Register error handlers
		Nuo::registerErrorHandlers();

		if ('production' != APPLICATION_ENV)
		{
			// Engine_Exception::setLog($log);
		}

		return $log;
	}

	protected function _initCache()
	{
		// Get configurations
		$file = APPLICATION_PATH . '/settings/cache.php';

		// @todo cache config in database

		if (file_exists($file))
		{
			// Manual config
			$options =
			include $file;
		}
		else
		if (is_writable(CACHE_PATH) || (!@is_dir(CACHE_PATH) && @mkdir(CACHE_PATH, 0777, true)))
		{
			// Auto default config
			$options = array(
					'default_backend' => 'File',
					'frontend' => array('core' => array(
								'automatic_serialization' => true,
								'cache_id_prefix' => 'Engine4_',
								'lifetime' => '300',
								'caching' => true,
						), ),
					'backend' => array('File' => array('cache_dir' => CACHE_PATH, ), ),
			);
		}
		else
		{
			// Failure
			return null;
		}

		// Create cache
		$frontend = key($options['frontend']);
		$backend = key($options['backend']);
		Nuo_Cache::setConfig($options);
		$cache = Nuo_Cache::factory($frontend, $backend);

		// Disable caching in development mode
		if (APPLICATION_ENV == 'development')
		{
			$cache -> setOption('caching', false);
		}

		// Save in registry
		Zend_Registry::set('Zend_Cache', $cache);

		// Add cache to database
		Zend_Db_Table_Abstract::setDefaultMetadataCache($cache);

		// Save in bootstrap
		return $cache;
	}

	/**
	 * Initializes translator
	 *
	 * @return Zend_Translate_Adapter
	 */
	public function _initTranslate()
	{

		// Set cache
		if (Zend_Registry::isRegistered('Zend_Cache'))
		{
			Zend_Translate::setCache(Zend_Registry::get('Zend_Cache'));
		}

		// If in development, log untranslated messages
		$params = array(
				'scan' => Zend_Translate_Adapter::LOCALE_DIRECTORY,
				'logUntranslated' => true
		);

		$log = new Zend_Log();

		if (APPLICATION_ENV == 'development')
		{
			$log = new Zend_Log();
			$log -> addWriter(new Zend_Log_Writer_Firebug());
			$log -> addWriter(new Zend_Log_Writer_Stream(LOG_PATH . '/translate.log'));
		}
		else
		{
			$log -> addWriter(new Zend_Log_Writer_Null());
		}
		$params['log'] = $log;

		// Main
		$translate = new Zend_Translate('Csv', APPLICATION_PATH . '/languages', null, $params);

		Zend_Registry::set('Zend_Translate', $translate);

		Zend_Validate_Abstract::setDefaultTranslator($translate);
		Zend_Form::setDefaultTranslator($translate);
		Zend_Controller_Router_Route::setDefaultTranslator($translate);

		return $translate;
	}

	protected function _initLocale()
	{

		// Try to pull from various sources
		// default timezone
		// default locale
		$viewer = Nuo::getViewer();

		// default timezone
		$defaultTimezone = 'UTC';

		$timezone = $defaultTimezone;

		// default locale
		// $locale = Nuo::getSetting('site.locale', 'auto');
		$locale = 'en';

		// default language
		$defaultLanguage = $locale;

		// get default locale setting;
		$defaultLocale = 'vi';

		if (is_object($viewer) && $viewer -> getId())
		{
			$locale = $viewer -> locale;
			$language = $viewer -> language;
			$timezone = $viewer -> timezone;
		}
		else
		if (!empty($_COOKIE['nuo_language']) && !empty($_COOKIE['nuo_language']))
		{
			$locale = $_COOKIE['nuo_locale'];
			$language = $_COOKIE['nuo_language'];
		}
		else
		{
			$language = $defaultLanguage;
		}

		Zend_Registry::set('timezone', $timezone);

		// Make sure it's valid
		try
		{
			$locale = Zend_Locale::findLocale($locale);
		}
		catch( Exception $e )
		{
			$locale = 'en_US';
		}
		try
		{
			$language = Zend_Locale::findLocale($language);
		}
		catch( Exception $e )
		{
			$language = 'en_US';
		}

		// Set in locale and language

		$localeObject = new Zend_Locale($locale);
		Zend_Registry::set('Locale', $localeObject);

		// Set in locale and language
		$translate = Zend_Registry::get('Zend_Translate');

		$selectedLanguage = $localeObject -> getLanguage();
		if (($selectedLocale = $localeObject -> getRegion()))
		{
			$selectedLanguage .= "_$selectedLocale";
		}

		if (!$translate -> isAvailable($selectedLanguage))
		{
			if (!$translate -> isAvailable($defaultLanguage))
			{
				$translate -> setLocale('en_US');
			}
			else
			{
				$translate -> setLocale($defaultLanguage);
			}
		}
		else
		{
			$translate -> setLocale($language);
		}

		// Set cache
		Zend_Locale_Data::setCache($this -> getContainer() -> cache);

		// Get orientation
		$localeData = Zend_Locale_Data::getList($localeObject -> __toString(), 'layout');

		return $localeObject;
	}

	protected function _initSession()
	{

		// Get session configuration
		$file = SETTING_PATH . '/session.php';
		$config = array();

		if (is_readable($file))
		{
			$config =
			include $file;
		}

		// Get default session configuration
		if (empty($config))
		{
			$config = array(
					'options' => array(
							'save_path' => 'session',
							'use_only_cookies' => true,
							'remember_me_seconds' => 864000,
							'gc_maxlifetime' => 86400,
							'cookie_httponly' => false,
					),
					'saveHandler' => array(
							'class' => 'Core_Model_DbTable_Session',
							'params' => array('lifetime' => 86400, ),
					),
			);
		}

		// Remove httponly unless forced in config
		if (!isset($config['options']['cookie_httponly']))
		{
			$config['options']['cookie_httponly'] = false;
		}

		// Set session options
		Zend_Session::setOptions($config['options']);

		$saveHandler = $config['saveHandler']['class'];
		Zend_Session::setSaveHandler(new $saveHandler($config['saveHandler']['params']));

		// Session hack for fancy upload
		//if( !isset($_COOKIE[session_name()]) )
		//{
		$sessionName = Zend_Session::getOptions('name');
		if (isset($_POST[$sessionName]))
		{
			Zend_Session::setId($_POST[$sessionName]);
		}
		else
		if (isset($_POST['PHPSESSID']))
		{
			Zend_Session::setId($_POST['PHPSESSID']);
		}
		//}

		//Zend_Session::start();
	}

}
